package net.lab1024.sa.admin.module.business.pdf.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;

/**
 * OCR诊断工具
 *
 * @Author 1024创新实验室
 */
@Slf4j
@Component
public class OcrDiagnosticTool {

    /**
     * 分析图像质量
     */
    public Map<String, Object> analyzeImageQuality(BufferedImage image) {
        Map<String, Object> analysis = new HashMap<>();
        
        if (image == null) {
            analysis.put("error", "图像为空");
            return analysis;
        }
        
        int width = image.getWidth();
        int height = image.getHeight();
        int totalPixels = width * height;
        
        analysis.put("width", width);
        analysis.put("height", height);
        analysis.put("totalPixels", totalPixels);
        analysis.put("aspectRatio", (double) width / height);
        
        // 计算平均亮度
        long totalBrightness = 0;
        int minBrightness = 255;
        int maxBrightness = 0;
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = image.getRGB(x, y);
                int gray = (rgb >> 16) & 0xFF; // 取红色分量作为灰度值
                totalBrightness += gray;
                minBrightness = Math.min(minBrightness, gray);
                maxBrightness = Math.max(maxBrightness, gray);
            }
        }
        
        double avgBrightness = (double) totalBrightness / totalPixels;
        int brightnessRange = maxBrightness - minBrightness;
        
        analysis.put("averageBrightness", avgBrightness);
        analysis.put("minBrightness", minBrightness);
        analysis.put("maxBrightness", maxBrightness);
        analysis.put("brightnessRange", brightnessRange);
        
        // 计算对比度
        double contrast = (double) brightnessRange / 255.0;
        analysis.put("contrast", contrast);
        
        // 质量评估
        String qualityLevel = assessImageQuality(avgBrightness, contrast, width, height);
        analysis.put("qualityLevel", qualityLevel);
        
        // 建议
        String suggestions = generateSuggestions(avgBrightness, contrast, width, height);
        analysis.put("suggestions", suggestions);
        
        return analysis;
    }
    
    /**
     * 评估图像质量等级
     */
    private String assessImageQuality(double avgBrightness, double contrast, int width, int height) {
        int score = 0;
        
        // 亮度评分
        if (avgBrightness >= 100 && avgBrightness <= 180) {
            score += 3; // 理想亮度范围
        } else if (avgBrightness >= 80 && avgBrightness <= 200) {
            score += 2; // 可接受亮度范围
        } else if (avgBrightness >= 50 && avgBrightness <= 230) {
            score += 1; // 勉强可接受
        }
        
        // 对比度评分
        if (contrast >= 0.6) {
            score += 3; // 高对比度
        } else if (contrast >= 0.4) {
            score += 2; // 中等对比度
        } else if (contrast >= 0.2) {
            score += 1; // 低对比度
        }
        
        // 分辨率评分
        int minDimension = Math.min(width, height);
        if (minDimension >= 1000) {
            score += 2; // 高分辨率
        } else if (minDimension >= 500) {
            score += 1; // 中等分辨率
        }
        
        // 根据总分确定质量等级
        if (score >= 7) {
            return "优秀";
        } else if (score >= 5) {
            return "良好";
        } else if (score >= 3) {
            return "一般";
        } else {
            return "较差";
        }
    }
    
    /**
     * 生成优化建议
     */
    private String generateSuggestions(double avgBrightness, double contrast, int width, int height) {
        StringBuilder suggestions = new StringBuilder();
        
        // 亮度建议
        if (avgBrightness < 80) {
            suggestions.append("1. 图像过暗，建议增加亮度\n");
        } else if (avgBrightness > 200) {
            suggestions.append("1. 图像过亮，建议降低亮度\n");
        }
        
        // 对比度建议
        if (contrast < 0.3) {
            suggestions.append("2. 对比度过低，建议增强对比度\n");
        }
        
        // 分辨率建议
        int minDimension = Math.min(width, height);
        if (minDimension < 500) {
            suggestions.append("3. 分辨率过低，建议提高DPI或图像质量\n");
        }
        
        if (suggestions.length() == 0) {
            suggestions.append("图像质量良好，无需特别优化");
        }
        
        return suggestions.toString();
    }
    
    /**
     * 保存诊断图像（用于调试）
     */
    public void saveDiagnosticImage(BufferedImage image, String filename) {
        try {
            File outputFile = new File("diagnostic_" + filename);
            ImageIO.write(image, "png", outputFile);
            log.info("诊断图像已保存: {}", outputFile.getAbsolutePath());
        } catch (IOException e) {
            log.error("保存诊断图像失败: {}", e.getMessage());
        }
    }
    
    /**
     * 分析OCR识别结果
     */
    public Map<String, Object> analyzeOcrResult(String ocrText) {
        Map<String, Object> analysis = new HashMap<>();
        
        if (ocrText == null || ocrText.trim().isEmpty()) {
            analysis.put("status", "失败");
            analysis.put("reason", "识别结果为空");
            return analysis;
        }
        
        String trimmedText = ocrText.trim();
        int length = trimmedText.length();
        
        analysis.put("textLength", length);
        analysis.put("originalText", trimmedText);
        
        // 计算中文字符比例
        int chineseChars = 0;
        int englishChars = 0;
        int digitChars = 0;
        int otherChars = 0;
        
        for (char c : trimmedText.toCharArray()) {
            if (Character.isDigit(c)) {
                digitChars++;
            } else if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
                englishChars++;
            } else if (c >= 0x4E00 && c <= 0x9FFF) { // 中文字符范围
                chineseChars++;
            } else {
                otherChars++;
            }
        }
        
        analysis.put("chineseChars", chineseChars);
        analysis.put("englishChars", englishChars);
        analysis.put("digitChars", digitChars);
        analysis.put("otherChars", otherChars);
        
        // 计算字符比例
        if (length > 0) {
            analysis.put("chineseRatio", (double) chineseChars / length);
            analysis.put("englishRatio", (double) englishChars / length);
            analysis.put("digitRatio", (double) digitChars / length);
            analysis.put("otherRatio", (double) otherChars / length);
        }
        
        // 评估识别质量
        String quality = assessOcrQuality(chineseChars, englishChars, digitChars, otherChars, length);
        analysis.put("quality", quality);
        
        return analysis;
    }
    
    /**
     * 评估OCR识别质量
     */
    private String assessOcrQuality(int chineseChars, int englishChars, int digitChars, int otherChars, int totalLength) {
        if (totalLength == 0) {
            return "失败";
        }
        
        // 计算有效字符比例（中英文数字）
        int validChars = chineseChars + englishChars + digitChars;
        double validRatio = (double) validChars / totalLength;
        
        // 计算其他字符比例（可能是识别错误）
        double otherRatio = (double) otherChars / totalLength;
        
        if (validRatio >= 0.8 && otherRatio <= 0.1) {
            return "优秀";
        } else if (validRatio >= 0.6 && otherRatio <= 0.2) {
            return "良好";
        } else if (validRatio >= 0.4 && otherRatio <= 0.3) {
            return "一般";
        } else {
            return "较差";
        }
    }
} 